﻿using CuaHangLego.DataAccess;
using CuaHangLego.Model;
using System;
using System.Collections;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;
using Excel = Microsoft.Office.Interop.Excel;

namespace CuaHangLego.Bussiness
{
    public class HoaDonBanBSS : IModelBSS<HoaDonBan>
    {
        public IList<HoaDonBan> ListHD { get; private set; }

        public HoaDonBanBSS()
        {
            this.ListHD = new List<HoaDonBan>();
            UpdateData();
        }

        public void UpdateData()
        {
            this.ListHD = HoaDonBanDA.Instance.GetAll().OrderByDescending(hd => hd.ThoiGian).ToList();
        }

        public void Add(HoaDonBan item)
        {
            item.StateType = BaseModel.StateTypes.WillBeAdd;
            this.ListHD.Add(item);
        }

        public void Edit(HoaDonBan item)
        {
            if (item.StateType == BaseModel.StateTypes.NoChange) item.StateType = BaseModel.StateTypes.WillBeChange;
            for (int i = 0; i < this.ListHD.Count; i++)
            {
                if (this.ListHD[i].MaSo == item.MaSo)
                {
                    this.ListHD[i] = item;
                    break;
                }
            }
        }

        public void Remove(HoaDonBan item)
        {
            if (item.StateType == BaseModel.StateTypes.NoChange) item.StateType = BaseModel.StateTypes.WillBeRemove;
            for (int i = 0; i < this.ListHD.Count; i++)
            {
                if (this.ListHD[i].MaSo == item.MaSo)
                {
                    this.ListHD[i] = item;
                    break;
                }
            }
        }

        public Hashtable Commit()
        {
            IList<string> missingInsert = new List<string>();
            IList<string> missingUpdate = new List<string>();
            IList<string> missingDelete = new List<string>();
            Hashtable missing = new Hashtable();
            int rsint = -1;
            bool rsbool = false;
            foreach (HoaDonBan kspr in this.ListHD)
            {
                switch (kspr.StateType)
                {
                    case BaseModel.StateTypes.WillBeAdd:
                        rsint = HoaDonBanDA.Instance.Insert(kspr);
                        if (rsint < 0) missingInsert.Add(kspr.ThoiGian + ":" + kspr.KhachHang.HoTen);
                        break;
                    case BaseModel.StateTypes.WillBeChange:
                        rsbool = HoaDonBanDA.Instance.Update(kspr);
                        if (!rsbool) missingUpdate.Add(kspr.MaSo.ToString());
                        break;
                    case BaseModel.StateTypes.WillBeRemove:
                        rsbool = HoaDonBanDA.Instance.Delete(kspr);
                        if (!rsbool) missingUpdate.Add(kspr.MaSo.ToString());
                        break;
                    default:
                        break;
                }
            }

            missing.Add("insert", missingInsert);
            missing.Add("update", missingUpdate);
            missing.Add("delete", missingDelete);

            return missing;
        }

        public IList<SanPham> CheckQuantity(HoaDonBan item)
        {
            IList<SanPham> NEList = new List<SanPham>();
            foreach (CTHD ct in item.DsCTHD)
            {
                if (SanPhamDA.Instance.GetQuantity(ct.SanPham.MaSo) - ct.SoLuong < 0)
                    NEList.Add(ct.SanPham);
            }
            return NEList;
        }

        public void Export(HoaDonBan hd)
        {
            string dir = "C:";
            FolderBrowserDialog dlg = new System.Windows.Forms.FolderBrowserDialog();
            DialogResult result = dlg.ShowDialog();
            if (result == System.Windows.Forms.DialogResult.OK)
            {

                dir = dlg.SelectedPath;
                Excel.Application xlApp;
                Excel.Workbook xlWorkBook;
                Excel.Worksheet xlWorkSheet;
                object misValue = System.Reflection.Missing.Value;
                Excel.Range chartRange;
                DateTime date = DateTime.Now;
                string link = "\\HoaDonBan_" + hd.MaSo + "_" + date.Year.ToString() + date.Month.ToString() + date.Day.ToString() + "_" + date.Hour.ToString() + date.Minute + date.Second + ".xls";

                xlApp = new Excel.Application();

                xlApp.StandardFont = "Arial";
                xlApp.StandardFontSize = 11;
                xlWorkBook = xlApp.Workbooks.Add(misValue);
                xlWorkSheet = (Excel.Worksheet)xlWorkBook.Worksheets.get_Item(1);
                xlWorkSheet.Name = "HOADONBAN";

                xlWorkSheet.get_Range("A1", "E1").Merge(false);
                xlWorkSheet.get_Range("A1", "E1").Font.ColorIndex = 43;
                xlWorkSheet.get_Range("A1", "E1").Font.Size = 22;
                xlWorkSheet.Cells[1, 1] = "THÔNG TIN HÓA ĐƠN";

                xlWorkSheet.Cells[2, 1] = "Mã hóa đơn";
                xlWorkSheet.Cells[3, 1] = "Khách hàng";
                xlWorkSheet.Cells[4, 1] = "Thời gian";
                xlWorkSheet.Cells[2, 2] = "#" + hd.MaSo;
                xlWorkSheet.Cells[3, 2] = hd.KhachHang.HoTen;
                xlWorkSheet.Cells[4, 2] = hd.ThoiGian.ToString();

                xlWorkSheet.get_Range("A5", "E5").Font.Bold = true;
                xlWorkSheet.get_Range("A5", "E5").Interior.ColorIndex = 43;
                xlWorkSheet.get_Range("A5", "E5").HorizontalAlignment = Excel.XlHAlign.xlHAlignCenter;
                xlWorkSheet.Cells[5, 1] = "STT";
                xlWorkSheet.Cells[5, 2] = "Sản phẩm";
                xlWorkSheet.Cells[5, 3] = "Đơn giá";
                xlWorkSheet.Cells[5, 4] = "Số lượng";
                xlWorkSheet.Cells[5, 5] = "Thành tiền";

                for (int i = 0; i < hd.DsCTHD.Count; i++)
                {
                    xlWorkSheet.Cells[i + 6, 1] = i + 1;
                    xlWorkSheet.Cells[i + 6, 2] = hd.DsCTHD[i].SanPham.Ten;
                    xlWorkSheet.Cells[i + 6, 3] = hd.DsCTHD[i].SanPham.GiaBan * 1000;
                    xlWorkSheet.Cells[i + 6, 4] = hd.DsCTHD[i].SoLuong;
                    xlWorkSheet.Cells[i + 6, 5] = string.Format("=(C{0}*D{0})", i + 6);
                }
                xlWorkSheet.Cells[hd.DsCTHD.Count + 6, 4] = "Tổng cộng";
                xlWorkSheet.Cells[hd.DsCTHD.Count + 6, 5] = string.Format("=SUM(E{0}:E{1})", 6, hd.DsCTHD.Count + 5);
                xlWorkSheet.Cells[hd.DsCTHD.Count + 6, 3].Font.Bold = true;
                xlWorkSheet.Cells[hd.DsCTHD.Count + 6, 4].Font.Bold = true;
                chartRange = xlWorkSheet.get_Range("A1", "Z200");
                chartRange.Columns.AutoFit();

                try
                {
                    xlWorkBook.SaveAs(dir + link, Excel.XlFileFormat.xlWorkbookNormal, misValue, misValue, misValue, misValue, Excel.XlSaveAsAccessMode.xlExclusive, misValue, misValue, misValue, misValue, misValue);
                }
                catch
                {
                    MessageBox.Show("Không thể lưu file!");
                }
                finally
                {
                    xlWorkBook.Close(true, misValue, misValue);
                    xlApp.Quit();
                }

                releaseObject(xlApp);
                releaseObject(xlWorkBook);
                releaseObject(xlWorkSheet);

                MessageBox.Show("Đã tạo report tại " + dir + link);
            }
        }
        private void releaseObject(object obj)
        {
            try
            {
                System.Runtime.InteropServices.Marshal.ReleaseComObject(obj);
                obj = null;
            }
            catch (Exception ex)
            {
                obj = null;
                MessageBox.Show("Unable to release the Object " + ex.ToString());
            }
            finally
            {
                GC.Collect();
            }
        }

        // linq

        public IList<HoaDonBan> GetHoaDonBanBy(string key, DateTime d1, DateTime d2)
        {
            var data = this.ListHD.Where(hd => (hd.KhachHang.HoTen.ToLower().Contains(key.ToLower())
                && DateTime.Parse(hd.ThoiGian.ToShortDateString()) >= DateTime.Parse(d1.ToShortDateString())
                && DateTime.Parse(hd.ThoiGian.ToShortDateString()) <= DateTime.Parse(d2.ToShortDateString())));
            return data.ToList();
        }

        public IList<HoaDonBan> GetHoaDonBanAll()
        {
            return this.ListHD;
        }
    }
}
